package objects;

import java.util.Calendar;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AlarmSnoozing extends AlarmState {
	private Calendar snoozeTime;

	private int snoozeCount = 0;
	private int threadCount = 0;

	ScheduledThreadPoolExecutor timerSched = new ScheduledThreadPoolExecutor(1);

	@Override
	public AlarmState init() {
		threadCount = 0;
		return this;
	}

	@Override
	/**
	 * Reacts depending upon snoozeCount's value.
	 */
	public AlarmState snooze(int timeLapse) {
		if (checkSnoozeCondition()) {
			resetTime();
			System.out.println("Snooze Stop");
			return alarmSet;
		}
		countSnooze(timeLapse);
		return alarmMakingNoise;
	}

	private void countSnooze(int timeLapse) {
		threadCount++;
		if (threadCount <= 1) {
			snoozeTime = timeSet;
			snoozeTime.set(Calendar.MINUTE,
					Calendar.getInstance().get(Calendar.MINUTE) + timeLapse);
			snoozeCount++;
			timerSched.schedule(alarmMakingNoise, snoozeTime.getTimeInMillis()
					- Calendar.getInstance().getTimeInMillis(),
					TimeUnit.MILLISECONDS);
		}
	}

	private void resetTime() {
		// We set up the next time...
		timeSet.set(Calendar.DAY_OF_YEAR, timeSet.get(Calendar.DAY_OF_YEAR) + 1);
		// ...and reset the alarm.
		alarmSet.alarmOn(timeSet);
		this.exit();
	}

	private boolean checkSnoozeCondition() {
		return snoozeCount >= 3
				&& snoozeTime.getTimeInMillis() < Calendar.getInstance()
						.getTimeInMillis();
	}

	@Override
	/**
	 * Resets the snoozeCount and the timerSched.
	 * 
	 * We should call this method every time we stop the alarm, just in case.
	 */
	public AlarmState exit() {
		snoozeCount = 0;
		return alarmSnoozing;
	}
}
